import { useUpdateEffect } from 'ahooks';
import { Icon, Spin, Tree } from 'antd';
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import isFunction from 'lodash/isFunction';
import PubSub from 'pubsub-js';
import useCatalogTree from '@/hooks/UseCatalogTree';

const { TreeNode } = Tree;

const getParentKey = (key, treeNodes) => {
  for (const node of treeNodes) {
    if (node.children) {
      if (node.children.some(child => child.key === key)) {
        return node.key;
      }
      if (getParentKey(key, node.children)) {
        return getParentKey(key, node.children);
      }
    }
  }
  return null;
};

function SearchableTree(
  {
    keyword = '',
    leafIcon = 'appstore',
    leafName,
    disableKeys = [],
    renderTitle,
    loading = false,
    onSelect,
  },
  ref
) {
  const { data: treeData, nodeList, loading: treeLoading, refresh } = useCatalogTree(leafName, {
    withLeaves: true,
  });
  const [expandedKeys, setExpandedKeys] = useState([]);
  const [autoExpandParent, setAutoExpandParent] = useState(true);

  useImperativeHandle(ref, () => ({
    refresh,
  }));

  const renderTreeNodes = nodes => {
    return nodes.map(node => {
      const nodeProps = {
        title: isFunction(renderTitle) ? renderTitle(node) : node.title,
        isLeaf: node.leaf,
        key: node.key,
        dataRef: node,
        disabled: disableKeys.includes(node.key),
      };
      return node.leaf ? (
        <TreeNode icon={<Icon type={leafIcon} />} {...nodeProps} />
      ) : (
        <TreeNode
          icon={({ expanded }) => <Icon type={expanded ? 'folder-open' : 'folder'} />}
          {...nodeProps}
        >
          {renderTreeNodes(node.children)}
        </TreeNode>
      );
    });
  };

  useUpdateEffect(() => {
    if (keyword) {
      const expandedKeys = nodeList
        .map(item => {
          if (item.title.includes(keyword)) {
            return getParentKey(item.key, treeData);
          }
          return null;
        })
        .filter(Boolean);
      setExpandedKeys(expandedKeys);
      setAutoExpandParent(true);
    }
  }, [keyword]);

  const onExpand = expandedKeys => {
    setExpandedKeys(expandedKeys);
    setAutoExpandParent(false);
  };

  return (
    <Spin spinning={treeLoading || loading}>
      <Tree
        showIcon
        autoExpandParent={autoExpandParent}
        onSelect={(_keys, e) => onSelect && onSelect(e)}
        expandedKeys={expandedKeys}
        onExpand={onExpand}
      >
        <TreeNode title="全部" key="-1" isLeaf dataRef={{ key: '-1', catalogId: '-1' }} />
        {treeData && renderTreeNodes(treeData)}
      </Tree>
    </Spin>
  );
}

export default forwardRef(SearchableTree);
